package cn.iocoder.yudao.module.bpm.message.config;


import cn.iocoder.yudao.framework.mq.redis.config.YudaoRedisMQConsumerAutoConfiguration;
import cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate;
import cn.iocoder.yudao.framework.mq.rocketmq.api.producer.service.ProducerMQService;
import cn.iocoder.yudao.module.bpm.message.ProcessInstanceMessage;
import cn.iocoder.yudao.module.bpm.message.ProcessTaskMessage;
import cn.iocoder.yudao.module.bpm.message.consts.ProcessInstanceStreamKey;
import cn.iocoder.yudao.module.bpm.message.consts.ProcessTaskStreamKey;
import cn.iocoder.yudao.module.bpm.message.handle.ProcessInstanceMessageHandle;
import cn.iocoder.yudao.module.bpm.message.handle.ProcessTaskMessageHandle;
import cn.iocoder.yudao.module.bpm.message.kafka.KafkaProcessInstanceMessage;
import cn.iocoder.yudao.module.bpm.message.kafka.KafkaProcessTaskMessage;
import cn.iocoder.yudao.module.bpm.message.kafka.custom.processInstance.*;
import cn.iocoder.yudao.module.bpm.message.kafka.custom.processTask.KafkaProcessTaskAssignedCustom;
import cn.iocoder.yudao.module.bpm.message.kafka.custom.processTask.KafkaProcessTaskCancelledCustom;
import cn.iocoder.yudao.module.bpm.message.kafka.custom.processTask.KafkaProcessTaskCompletedCustom;
import cn.iocoder.yudao.module.bpm.message.kafka.custom.processTask.KafkaProcessTaskCreatedCustom;
import cn.iocoder.yudao.module.bpm.message.local.LocalProcessInstanceMessage;
import cn.iocoder.yudao.module.bpm.message.local.LocalProcessTaskMessage;
import cn.iocoder.yudao.module.bpm.message.rabbitmq.custom.processInstance.*;
import cn.iocoder.yudao.module.bpm.message.rabbitmq.RabbitMqProcessInstanceMessage;
import cn.iocoder.yudao.module.bpm.message.rabbitmq.RabbitMqProcessTaskMessage;
import cn.iocoder.yudao.module.bpm.message.rabbitmq.custom.processTask.RabbitMqProcessTaskAssignedCustom;
import cn.iocoder.yudao.module.bpm.message.rabbitmq.custom.processTask.RabbitMqProcessTaskCancelledCustom;
import cn.iocoder.yudao.module.bpm.message.rabbitmq.custom.processTask.RabbitMqProcessTaskCompletedCustom;
import cn.iocoder.yudao.module.bpm.message.rabbitmq.custom.processTask.RabbitMqProcessTaskCreatedCustom;
import cn.iocoder.yudao.module.bpm.message.redis.RedisProcessInstanceMessage;
import cn.iocoder.yudao.module.bpm.message.redis.RedisProcessTaskMessage;
import cn.iocoder.yudao.module.bpm.message.redis.custom.processInstance.*;
import cn.iocoder.yudao.module.bpm.message.redis.custom.processTask.RedisProcessTaskAssignedCustom;
import cn.iocoder.yudao.module.bpm.message.redis.custom.processTask.RedisProcessTaskCancelledCustom;
import cn.iocoder.yudao.module.bpm.message.redis.custom.processTask.RedisProcessTaskCompletedCustom;
import cn.iocoder.yudao.module.bpm.message.redis.custom.processTask.RedisProcessTaskCreatedCustom;
import cn.iocoder.yudao.module.bpm.message.rocketmq.RocketMqProcessInstanceMessage;
import cn.iocoder.yudao.module.bpm.message.rocketmq.RocketMqProcessTaskMessage;
import cn.iocoder.yudao.module.bpm.message.rocketmq.custom.processInstance.*;
import cn.iocoder.yudao.module.bpm.message.rocketmq.custom.processTask.RocketMqProcessTaskAssignedCustom;
import cn.iocoder.yudao.module.bpm.message.rocketmq.custom.processTask.RocketMqProcessTaskCancelledCustom;
import cn.iocoder.yudao.module.bpm.message.rocketmq.custom.processTask.RocketMqProcessTaskCompletedCustom;
import cn.iocoder.yudao.module.bpm.message.rocketmq.custom.processTask.RocketMqProcessTaskCreatedCustom;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.core.KafkaTemplate;

@AutoConfiguration(before = YudaoRedisMQConsumerAutoConfiguration.class) // before YudaoRedisMQConsumerAutoConfiguration 的原因是，需要保证 RedisWebSocketMessageConsumer 先创建，才能创建 RedisMessageListenerContainer
@Log4j2
public class BpmMessageAutoConfiguration {

    public BpmMessageAutoConfiguration(@Value("${yudao.bpm-message.sender-type}") String senderType){
        log.info("[init][BpmMessage 实现]:{}",senderType);
    }


    @Configuration
    @ConditionalOnProperty(prefix = "yudao.bpm-message", name = "sender-type", havingValue = "local", matchIfMissing = true)
    public class LocalWebSocketMessageSenderConfiguration {
        @Bean
        public ProcessInstanceMessage localProcessInstanceMessage(
                ProcessInstanceMessageHandle processInstanceMessageHandle,
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new LocalProcessInstanceMessage(processInstanceMessageHandle, processTaskMessageHandle);
        }

        @Bean
        public ProcessTaskMessage localProcessTaskMessage(
                ProcessInstanceMessageHandle processInstanceMessageHandle,
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new LocalProcessTaskMessage(processInstanceMessageHandle,processTaskMessageHandle);
        }

    }

    @Configuration
    @ConditionalOnProperty(prefix = "yudao.bpm-message", name = "sender-type", havingValue = "redis", matchIfMissing = false)
    public class RedisWebSocketMessageSenderConfiguration {

        @Bean
        public ProcessInstanceMessage redisProcessInstanceMessage(
                RedisMQTemplate redisMQTemplate
        ) {
            return new RedisProcessInstanceMessage(redisMQTemplate);
        }
        @Bean
        public ProcessTaskMessage redisProcessTaskMessage(
                RedisMQTemplate redisMQTemplate
        ) {
            return new RedisProcessTaskMessage(redisMQTemplate);
        }
        @Bean
        public RedisProcessInstanceApproveCustom redisProcessInstanceApproveCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RedisProcessInstanceApproveCustom(processInstanceMessageHandle);
        }

        @Bean
        public RedisProcessInstanceCancelledCustom redisProcessInstanceCancelledCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RedisProcessInstanceCancelledCustom(processInstanceMessageHandle);
        }

        @Bean
        public RedisProcessInstanceCreatedCustom redisProcessInstanceCreatedCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RedisProcessInstanceCreatedCustom(processInstanceMessageHandle);
        }


        @Bean
        public RedisProcessInstanceRejectCustom redisProcessInstanceRejectCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RedisProcessInstanceRejectCustom(processInstanceMessageHandle);
        }

        @Bean
        public RedisProcessInstanceStartedCustom redisProcessInstanceStartedCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RedisProcessInstanceStartedCustom(processInstanceMessageHandle);
        }

        @Bean
        public RedisProcessTaskAssignedCustom redisProcessTaskAssignedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RedisProcessTaskAssignedCustom(processTaskMessageHandle);
        }
        @Bean
        public RedisProcessTaskCancelledCustom redisProcessTaskCancelledCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RedisProcessTaskCancelledCustom(processTaskMessageHandle);
        }
        @Bean
        public RedisProcessTaskCompletedCustom redisProcessTaskCompletedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RedisProcessTaskCompletedCustom(processTaskMessageHandle);
        }
        @Bean
        public RedisProcessTaskCreatedCustom redisProcessTaskCreatedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RedisProcessTaskCreatedCustom(processTaskMessageHandle);
        }


    }

    @Configuration
    @ConditionalOnProperty(prefix = "yudao.bpm-message", name = "sender-type", havingValue = "rocketmq", matchIfMissing = false)
    public class RocketMQWebSocketMessageSenderConfiguration {

        @Bean
        public ProcessInstanceMessage rocketMqProcessInstanceMessage(
                ProducerMQService rocketMQService
        ) {
            return new RocketMqProcessInstanceMessage(rocketMQService);
        }
        @Bean
        public ProcessTaskMessage rocketMqProcessTaskMessage(
                ProducerMQService rocketMQService
        ) {
            return new RocketMqProcessTaskMessage(rocketMQService);
        }
        @Bean
        public RocketMqProcessInstanceApproveCustom rocketMqProcessInstanceApproveCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RocketMqProcessInstanceApproveCustom(processInstanceMessageHandle);
        }

        @Bean
        public RocketMqProcessInstanceCancelledCustom rocketMqProcessInstanceCancelledCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RocketMqProcessInstanceCancelledCustom(processInstanceMessageHandle);
        }

        @Bean
        public RocketMqProcessInstanceCreatedCustom rocketMqProcessInstanceCreatedCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RocketMqProcessInstanceCreatedCustom(processInstanceMessageHandle);
        }


        @Bean
        public RocketMqProcessInstanceRejectCustom rocketMqProcessInstanceRejectCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RocketMqProcessInstanceRejectCustom(processInstanceMessageHandle);
        }

        @Bean
        public RocketMqProcessInstanceStartedCustom rocketMqProcessInstanceStartedCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RocketMqProcessInstanceStartedCustom(processInstanceMessageHandle);
        }

        @Bean
        public RocketMqProcessTaskAssignedCustom rocketMqProcessTaskAssignedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RocketMqProcessTaskAssignedCustom(processTaskMessageHandle);
        }
        @Bean
        public RocketMqProcessTaskCancelledCustom rocketMqProcessTaskCancelledCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RocketMqProcessTaskCancelledCustom(processTaskMessageHandle);
        }
        @Bean
        public RocketMqProcessTaskCompletedCustom rocketMqProcessTaskCompletedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RocketMqProcessTaskCompletedCustom(processTaskMessageHandle);
        }
        @Bean
        public RocketMqProcessTaskCreatedCustom rocketMqProcessTaskCreatedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RocketMqProcessTaskCreatedCustom(processTaskMessageHandle);
        }


    }

    @Configuration
    @ConditionalOnProperty(prefix = "yudao.bpm-message", name = "sender-type", havingValue = "rabbitmq", matchIfMissing = false)
    public class RabbitMQWebSocketMessageSenderConfiguration {
        public RabbitMQWebSocketMessageSenderConfiguration(){
            log.info("RabbitMQWebSocketMessageSenderConfiguration");
        }

        @Bean
        public ProcessInstanceMessage rabbitMqProcessInstanceMessage(
                RabbitTemplate rabbitTemplate
        ) {
            TopicExchange processInstanceCleanTopicExchange = new TopicExchange(ProcessInstanceStreamKey.PROCESS_INSTANCE_CLEAN_MSG_STREAM,
                    true,  // durable: 是否持久化
                    false);
            TopicExchange processInstanceFinishedTopicExchange = new TopicExchange(ProcessInstanceStreamKey.PROCESS_INSTANCE_FINISHED_MSG_STREAM,
                    true,  // durable: 是否持久化
                    false);
            TopicExchange processInstanceRejectTopicExchange = new TopicExchange(ProcessInstanceStreamKey.PROCESS_INSTANCE_REJECT_MSG_STREAM,
                    true,  // durable: 是否持久化
                    false);
            TopicExchange processInstanceCreatedTopicExchange = new TopicExchange(ProcessInstanceStreamKey.PROCESS_INSTANCE_CREATED_MSG_STREAM,
                    true,  // durable: 是否持久化
                    false);
            TopicExchange processInstanceStartedExchange = new TopicExchange(ProcessInstanceStreamKey.PROCESS_INSTANCE_STARTED_MSG_STREAM,
                    true,  // durable: 是否持久化
                    false);
            return new RabbitMqProcessInstanceMessage(
                    rabbitTemplate,
                    processInstanceCleanTopicExchange,
                    processInstanceFinishedTopicExchange,
                    processInstanceRejectTopicExchange,
                    processInstanceCreatedTopicExchange,
                    processInstanceStartedExchange
            );
        }
        @Bean
        public ProcessTaskMessage rabbitMqProcessTaskMessage(
                RabbitTemplate rabbitTemplate
        ) {
            TopicExchange processInstanceTaskCreatedTopicExchange = new TopicExchange(ProcessTaskStreamKey.PROCESS_INSTANCE_TASK_CREATED_MSG_STREAM,
                    true,  // durable: 是否持久化
                    false);
            TopicExchange processInstanceTaskAssignedTopicExchange = new TopicExchange(ProcessTaskStreamKey.PROCESS_INSTANCE_TASK_ASSIGNED_MSG_STREAM,
                    true,  // durable: 是否持久化
                    false);
            TopicExchange processInstanceTaskCleanTopicExchange = new TopicExchange(ProcessTaskStreamKey.PROCESS_INSTANCE_TASK_CLEAN_MSG_STREAM,
                    true,  // durable: 是否持久化
                    false);
            TopicExchange processInstanceTaskFinishedTopicExchange = new TopicExchange(ProcessTaskStreamKey.PROCESS_INSTANCE_TASK_FINISHED_MSG_STREAM,
                    true,  // durable: 是否持久化
                    false);
            return new RabbitMqProcessTaskMessage(
                    rabbitTemplate,
                    processInstanceTaskCreatedTopicExchange,
                    processInstanceTaskAssignedTopicExchange,
                    processInstanceTaskCleanTopicExchange,
                    processInstanceTaskFinishedTopicExchange
            );
        }
        @Bean
        public RabbitMqProcessInstanceApproveCustom rabbitMqProcessInstanceApproveCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RabbitMqProcessInstanceApproveCustom(processInstanceMessageHandle);
        }

        @Bean
        public RabbitMqProcessInstanceCancelledCustom rabbitMqProcessInstanceCancelledCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RabbitMqProcessInstanceCancelledCustom(processInstanceMessageHandle);
        }

        @Bean
        public RabbitMqProcessInstanceCreatedCustom rabbitMqProcessInstanceCreatedCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RabbitMqProcessInstanceCreatedCustom(processInstanceMessageHandle);
        }


        @Bean
        public RabbitMqProcessInstanceRejectCustom rabbitMqProcessInstanceRejectCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RabbitMqProcessInstanceRejectCustom(processInstanceMessageHandle);
        }

        @Bean
        public RabbitMqProcessInstanceStartedCustom rabbitMqProcessInstanceStartedCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new RabbitMqProcessInstanceStartedCustom(processInstanceMessageHandle);
        }

        @Bean
        public RabbitMqProcessTaskAssignedCustom rabbitMqProcessTaskAssignedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RabbitMqProcessTaskAssignedCustom(processTaskMessageHandle);
        }
        @Bean
        public RabbitMqProcessTaskCancelledCustom rabbitMqProcessTaskCancelledCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RabbitMqProcessTaskCancelledCustom(processTaskMessageHandle);
        }
        @Bean
        public RabbitMqProcessTaskCompletedCustom rabbitMqProcessTaskCompletedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RabbitMqProcessTaskCompletedCustom(processTaskMessageHandle);
        }
        @Bean
        public RabbitMqProcessTaskCreatedCustom rabbitMqProcessTaskCreatedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new RabbitMqProcessTaskCreatedCustom(processTaskMessageHandle);
        }



    }

    @Configuration
    @ConditionalOnProperty(prefix = "yudao.bpm-message", name = "sender-type", havingValue = "kafka", matchIfMissing = false)
    public class KafkaWebSocketMessageSenderConfiguration {

        @Bean
        public ProcessInstanceMessage kafkaProcessInstanceMessage(
                KafkaTemplate<Object, Object> kafkaTemplate
        ) {
            return new KafkaProcessInstanceMessage(
                    kafkaTemplate,
                    ProcessInstanceStreamKey.PROCESS_INSTANCE_CLEAN_MSG_STREAM,
                    ProcessInstanceStreamKey.PROCESS_INSTANCE_FINISHED_MSG_STREAM,
                    ProcessInstanceStreamKey.PROCESS_INSTANCE_REJECT_MSG_STREAM,
                    ProcessInstanceStreamKey.PROCESS_INSTANCE_CREATED_MSG_STREAM,
                    ProcessInstanceStreamKey.PROCESS_INSTANCE_STARTED_MSG_STREAM
            );
        }
        @Bean
        public ProcessTaskMessage kafkaProcessTaskMessage(
                KafkaTemplate<Object, Object> kafkaTemplate
        ) {
            return new KafkaProcessTaskMessage(
                    kafkaTemplate,
                    ProcessTaskStreamKey.PROCESS_INSTANCE_TASK_CREATED_MSG_STREAM,
                    ProcessTaskStreamKey.PROCESS_INSTANCE_TASK_ASSIGNED_MSG_STREAM,
                    ProcessTaskStreamKey.PROCESS_INSTANCE_TASK_CLEAN_MSG_STREAM,
                    ProcessTaskStreamKey.PROCESS_INSTANCE_TASK_FINISHED_MSG_STREAM
            );
        }
        @Bean
        public KafkaProcessInstanceApproveCustom kafkaProcessInstanceApproveCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new KafkaProcessInstanceApproveCustom(processInstanceMessageHandle);
        }

        @Bean
        public KafkaProcessInstanceCancelledCustom kafkaProcessInstanceCancelledCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new KafkaProcessInstanceCancelledCustom(processInstanceMessageHandle);
        }

        @Bean
        public KafkaProcessInstanceCreatedCustom kafkaProcessInstanceCreatedCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new KafkaProcessInstanceCreatedCustom(processInstanceMessageHandle);
        }


        @Bean
        public KafkaProcessInstanceRejectCustom kafkaProcessInstanceRejectCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new KafkaProcessInstanceRejectCustom(processInstanceMessageHandle);
        }

        @Bean
        public KafkaProcessInstanceStartedCustom kafkaProcessInstanceStartedCustom(
                ProcessInstanceMessageHandle processInstanceMessageHandle
        ) {
            return new KafkaProcessInstanceStartedCustom(processInstanceMessageHandle);
        }

        @Bean
        public KafkaProcessTaskAssignedCustom kafkaProcessTaskAssignedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new KafkaProcessTaskAssignedCustom(processTaskMessageHandle);
        }
        @Bean
        public KafkaProcessTaskCancelledCustom kafkaProcessTaskCancelledCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new KafkaProcessTaskCancelledCustom(processTaskMessageHandle);
        }
        @Bean
        public KafkaProcessTaskCompletedCustom kafkaProcessTaskCompletedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new KafkaProcessTaskCompletedCustom(processTaskMessageHandle);
        }
        @Bean
        public KafkaProcessTaskCreatedCustom kafkaProcessTaskCreatedCustom(
                ProcessTaskMessageHandle processTaskMessageHandle
        ) {
            return new KafkaProcessTaskCreatedCustom(processTaskMessageHandle);
        }


    }

}
